/* 
 * File:   IPToolkit.h
 * Author: liuyi
 *
 * Created on August 20, 2009, 4:28 PM
 */

#ifndef _IPTOOLKIT_H
#define	_IPTOOLKIT_H

typedef unsigned char uchar;

class Point {
public:
    int x;
    int y;

    Point() {
    }

    Point(int xI, int yI) {
        x = xI;
        y = yI;
    }

};

class Rect {
public:
    int x;
    int y;
    int width;
    int height;

    Rect() {
    }

    Rect(int xI, int yI, int widthI, int heightI) {
        x = xI;
        y = yI;
        width = widthI;
        height = heightI;
    }

};

class Morphology {
public:
    class StructElem {
    public:
        int rows;
        int cols;
        Point anchor;
        uchar *data;

        StructElem(int r, int c, int x, int y): anchor(x, y) {
            rows = r;
            cols = c;
            data = new uchar[rows * cols];
        }

        ~StructElem() {
            delete[] data;
        }
    };

    // if dst == NULL, operate on src
    void erode(uchar *dst, const uchar *src, int width, int height, StructElem &elem, int iteration = 1);

    // if dst == NULL, operate on src
    void dilate(uchar *dst, const uchar *src, int width, int height, StructElem &elem, int iteration = 1);

    Morphology(uchar front, uchar bg) {
        m_front = front;
        m_bg = bg;
    }

private:
    uchar m_front;
    uchar m_bg;

};

class IPToolkit {
public:
    enum Intrplt { NEAREST, LINER };

    static void fillConnetecd(uchar *imageData, int width, int height, const Point seed, uchar value);
    
    static void resize(uchar *dst, int dW, int dH, const uchar *src, int sW, int sH, Intrplt method = LINER);

    static void binarize(uchar *imageData, int width, int height, uchar theta);

private:
    class PointPair {
    public:
        Point p;
        Point dir;

        PointPair(Point pI, Point dirI) {
            p = pI;
            dir = dirI;
        }

    };

    static bool nextDir(Point &dir) {
        if(dir.x == -1 && dir.y == 0) {
            return false;
        }

        int x = dir.x;

        dir.x -= dir.y;
        dir.y = x + dir.y;

        if (dir.x == 2 || dir.x == -2) {
            dir.x /= 2;
        }
        if (dir.y == 2 || dir.y == -2) {
            dir.y /= 2;
        }

        return true;
    }

    IPToolkit();
    IPToolkit(const IPToolkit& orig);
    virtual ~IPToolkit();

};

#endif	/* _IPTOOLKIT_H */

